import china from '@/assets/map/china.json';
import bg from '@/assets/screen/index/bg.png';
import fault from '@/assets/screen/index/fault.png';
import low from '@/assets/screen/index/low.png';
import off from '@/assets/screen/index/off.png';
import perfect from '@/assets/screen/index/perfect.png';
import topbar from '@/assets/screen/index/topbar.png';
import { ReactComponent as diamond } from '@/assets/screen/symbolIcon/diamond.svg';
import { ReactComponent as pentagram } from '@/assets/screen/symbolIcon/pentagram.svg';
import { ReactComponent as plum } from '@/assets/screen/symbolIcon/plum.svg';
import { ReactComponent as rect } from '@/assets/screen/symbolIcon/rect.svg';
import { ReactComponent as trapezium } from '@/assets/screen/symbolIcon/trapezium.svg';
import { ReactComponent as triangle } from '@/assets/screen/symbolIcon/triangle.svg';
import BaseEchart from '@/components/base/BaseEchart';
import BaseModal from '@/components/base/BaseModal';
import { getRadarMapStatus } from '@/pages/Index/api';
import useUserStore from '@/store/user';
import { requestStatic, useRequest } from '@/utils/request';
import { BackwardOutlined, MinusOutlined, PlusOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import * as echarts from 'echarts';
import EChartsReact from 'echarts-for-react';
import { useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import { pollingInterval } from '../api';
import Box from '../components/Box';
import NowDate from '../components/NowDate';
import { fixHeight, fixWidth } from '../util';

echarts.registerMap('china', china as any);
// eslint-disable-next-line require-jsdoc
function IsWithin(pt: [number, number], polygon: [number, number][], noneZeroMode: boolean) {
  const ptNum = polygon.length;
  if (ptNum < 3) {
    return false;
  }
  let j = ptNum - 1;
  let oddNodes = false;
  let zeroState = 0;
  for (let k = 0; k < ptNum; k += 1) {
    const ptK = polygon[k];
    const ptJ = polygon[j];
    if (
      ptK[1] > pt[1] !== ptJ[1] > pt[1] &&
      pt[0] < ((ptJ[0] - ptK[0]) * (pt[1] - ptK[1])) / (ptJ[1] - ptK[1]) + ptK[0]
    ) {
      oddNodes = !oddNodes;
      if (ptK[1] > ptJ[1]) {
        zeroState += 1;
      } else {
        zeroState -= 1;
      }
    }
    j = k;
  }
  return noneZeroMode ? zeroState !== 0 : oddNodes;
}
const IndexLayout = styled.div`
  background-image: url('${bg}');
  background-size: 100% 100%;
  position: absolute;
  width: 100%;
  height: 100%;
  .title-wrap {
    background-image: url('${topbar}');
    background-size: 100% 100%;
    height: ${fixHeight(89)};
    position: relative;
    text-align: center;
    color: #fff;
    .title {
      line-height: ${fixHeight(89)};
      font-size: ${fixHeight(40)};
      font-family: header-title !important;
    }
    .topbar-left {
      width: ${fixWidth(420)};
      position: absolute;
      text-align: left;
      bottom: ${fixHeight(4)};
      left: 0;
      padding-left: ${fixWidth(8)};
      line-height: ${fixHeight(30)};
    }
    .topbar-right {
      width: ${fixWidth(420)};
      position: absolute;
      bottom: ${fixHeight(8)};
      right: 0;
      text-align: right;
      padding-right: ${fixWidth(16)};
      font-size: ${fixHeight(13)};
      line-height: ${fixHeight(28)};
      span + span {
        margin-left: ${fixWidth(8)};
      }
    }
  }
  .map {
    height: ${fixHeight(970)};
    width: ${fixWidth(1360)};
    position: absolute;
    left: ${fixWidth(20)};
    top: ${fixHeight(90)};
    &-chart {
      width: 100%;
      height: 100%;
      position: relative;
    }
    .legend-data {
      position: absolute;
      bottom: ${fixHeight(20)};
      left: ${fixWidth(20)};
      z-index: 1;
      display: flex;
      background: #00637c;
      padding: ${fixHeight(20)};
      border-radius: ${fixHeight(20)};
      .legend-item {
        display: flex;
        align-items: center;
        font-size: ${fixHeight(12)};
        margin-top: ${fixHeight(6)};
        cursor: pointer;
        line-height: ${fixHeight(24)};
        &:first-child {
          margin-top: 0;
        }
        .icon {
          display: flex;
          align-items: center;
          justify-content: center;
          width: ${fixHeight(16)};
          height: ${fixHeight(16)};
          margin-right: ${fixWidth(8)};
          border-radius: 50%;
        }
        .symbol {
          display: flex;
          align-items: center;
          justify-content: center;
          width: ${fixHeight(24)};
          height: ${fixHeight(24)};
          margin-right: ${fixWidth(8)};
        }
      }
    }
    .action {
      position: absolute;
      top: ${fixHeight(20)};
      left: ${fixHeight(20)};
      z-index: 1;
      .zoom-action {
        background: rgba(10, 162, 175, 0.7);
        padding: ${fixHeight(8)};
        &-item {
          display: block;
          background: #04536b;
          width: ${fixHeight(32)};
          height: ${fixHeight(32)};
          line-height: ${fixHeight(32)};
          text-align: center;
          cursor: pointer;
          color: rgb(10, 162, 175);
          font-size: ${fixHeight(24)};
          & + .zoom-action-item {
            margin-top: ${fixHeight(12)};
          }
          &:hover {
            background: #05637c;
          }
        }
      }
    }
  }
  .right {
    position: absolute;
    right: ${fixWidth(20)};
    top: ${fixHeight(90)};
    height: ${fixHeight(970)};
    width: ${fixWidth(500)};
    display: flex;
    flex-direction: column;
    .radar-status {
      height: ${fixHeight(560)};
    }
    .monitor-list {
      height: ${fixHeight(970)};
      /* margin-top: ${fixHeight(20)}; */
      &-wrap {
        overflow: hidden;
      }
      &-item {
        height: ${fixHeight(82)};
        width: ${fixWidth(254)};
        margin: ${fixHeight(12)} auto;
        background-size: 100% 100%;
        position: relative;
        cursor: pointer;
        &.perfect {
          background-image: url('${perfect}');
        }
        &.low {
          background-image: url('${low}');
        }
        &.fault {
          background-image: url('${fault}');
        }
        &.off {
          background-image: url('${off}');
        }
        .item-content {
          position: absolute;
          right: 0;
          top: ${fixHeight(14)};
          width: ${fixWidth(100)};
          height: ${fixHeight(54)};
          display: flex;
          align-items: center;
          justify-content: center;
          flex-wrap: wrap;
          word-wrap: break-word;
          div {
            width: 100%;
            text-align: center;
          }
        }
      }
    }
  }
`;
const maps = ['china'];
const radarClick = (radarItem: any) => {
  const { area } = useUserStore.getState().userinfo;
  if (area.some((i) => i.areaId === radarItem.areaId)) {
    if (radarItem.isTableData !== 0) {
      window.location.href = `/monitor/radar?radarId=${radarItem.id}`;
    } else if (radarItem.status !== 4) {
      BaseModal.warning({
        title: '雷达接入警告',
        content: `雷达 ${radarItem.name} 暂无数据，无法查看详情`
      });
    } else {
      BaseModal.warning({
        title: '雷达接入警告',
        content: `雷达 ${radarItem.name} 暂未接入，无法查看详情`
      });
    }
  } else {
    BaseModal.warning({
      title: '权限警告',
      content: `您的区域与 ${radarItem.name} 雷达不相同，无法访问`
    });
  }
};
const icons = {
  diamond: {
    path: 'path://M3.404,0.298 L18.22,0.298 L21.427,4.957 L0.0,4.957 L3.404,0.298 ZM10.708,18.0 L0.9,4.968 L21.427,4.968 L10.708,18.0 Z',
    icon: diamond
  },
  pentagram: {
    path: 'path://M10.734,0.0 L14.466,5.320 L20.687,7.221 L16.773,12.410 L16.885,18.906 L10.734,16.792 L4.583,18.906 L4.695,12.410 L0.781,7.221 L7.1,5.320 L10.734,0.0 Z',
    icon: pentagram
  },
  plum: {
    path: 'path://M16.186,15.822 C16.186,18.625 13.914,20.897 11.111,20.897 C8.309,20.897 6.37,18.625 6.37,15.822 C3.234,15.822 0.962,13.550 0.962,10.748 C0.962,7.945 3.234,5.673 6.37,5.673 C6.37,2.871 8.309,0.599 11.111,0.599 C13.914,0.599 16.186,2.871 16.186,5.673 C18.988,5.673 21.260,7.945 21.260,10.748 C21.260,13.550 18.988,15.822 16.186,15.822 Z',
    icon: plum
  },
  rect: {
    path: 'path://M0.14,0.0 L16.0,0.0 L16.0,16.14 L0.14,16.14 L0.14,0.0 Z',
    icon: rect
  },
  trapezium: {
    path: 'path://M4.802,0.0 L17.197,0.0 L21.990,15.0 L0.9,15.0 L4.802,0.0 Z',
    icon: trapezium
  },
  triangle: {
    path: 'path://M11.500,0.0 L23.0,14.0 L0.0,14.0 L11.500,0.0 Z',
    icon: triangle
  }
};
const getSymbol = (symbolName = 'rect') => {
  const Icon = icons[symbolName as keyof typeof icons].icon;
  return <Icon />;
};
const Index = () => {
  const [activeMap, setActiveMap] = useState('china');
  const mapStacks = useRef(['china']);
  const radarMap = useRequest(getRadarMapStatus, { pollingInterval });
  const coordinates = useRef<[number, number][]>();
  const [zoom, setZoom] = useState(1.5);
  const chartRef = useRef<EChartsReact>(null);
  const [data, setData] = useState<any[]>([]);
  const [activeLegends, setActiveLegends] = useState<
    Record<number, { len: number; values: any[]; status: boolean }>
  >({
    0: { len: 0, values: [], status: true },
    1: { len: 0, values: [], status: true },
    2: { len: 0, values: [], status: true },
    3: { len: 0, values: [], status: true },
    4: { len: 0, values: [], status: true }
  });
  const [activeTypeLegends, setActiveTypeLegends] = useState<
    Record<string, { status: boolean; symbol: string }>
  >({});
  const legends = [
    {
      name: '正常',
      color: '#20df37'
    },
    {
      name: '弱化',
      color: '#faad14'
    },
    {
      name: '故障',
      color: '#e14849'
    },
    {
      name: '离线',
      color: '#aaa'
    },
    {
      name: '未接入',
      color: '#333'
    }
  ];

  useEffect(() => {
    const map: Record<string, { name: string; symbol: string; data: any[] }> = {};
    const legends: Record<number, { len: number; values: any[]; status: boolean }> = {
      0: { len: 0, values: [], status: true },
      1: { len: 0, values: [], status: true },
      2: { len: 0, values: [], status: true },
      3: { len: 0, values: [], status: true },
      4: { len: 0, values: [], status: true }
    };
    const typeLegends: Record<string, { status: boolean; symbol: string }> = {};
    const itudes: string[] = [];

    (radarMap.data?.RaRadarMapVOS || []).forEach((i) => {
      let longitude = Number(i.longitude);
      let latitude = Number(i.latitude);
      const has = coordinates.current
        ? IsWithin([longitude, latitude], coordinates.current, true)
        : true;
      if (has) {
        const str = `${longitude}${latitude}`;
        if (itudes.includes(str)) {
          longitude *= 1 + Math.random() * 0.00005;
          latitude *= 1 + Math.random() * 0.00005;
        } else {
          itudes.push(str);
        }
        if (!(i.radarTypeName in map)) {
          map[i.radarTypeName] = {
            data: [],
            name: i.radarTypeName,
            symbol: i.tabShap
          };
        }
        map[i.radarTypeName].data.push({
          value: [
            longitude,
            latitude,
            i.status,
            i.radarTypeName,
            i.areaName,
            i.stationName,
            i.name,
            i.id
          ],
          label: i.name
        });
        legends[i.status as number].len += 1;
        legends[i.status as number].values.push(i);
        legends[i.status as number].status = activeLegends[i.status as number].status;
        if (!typeLegends[i.radarTypeName]) {
          typeLegends[i.radarTypeName] = { symbol: '', status: true };
        }
        typeLegends[i.radarTypeName].symbol = i.tabShap;
        typeLegends[i.radarTypeName].status = activeTypeLegends[i.radarTypeName]?.status ?? true;
      }
    });
    setData(Object.values(map));
    setActiveLegends(legends);
    setActiveTypeLegends(typeLegends);
    let index = 0;
    let framer = 0;
    let sleep = 125;
    const animate = () => {
      const wrap = document.querySelector('.monitor-list-wrap');
      if (wrap) {
        const { scrollTop, clientHeight, scrollHeight } = wrap;
        if (
          (parseInt(`${index}`) % 80 === 0 || scrollHeight - clientHeight - scrollTop <= 10) &&
          sleep !== 0
        ) {
          sleep -= 1;
        } else {
          sleep = 125;
          if (scrollHeight - clientHeight - scrollTop <= 10) {
            index = 0;
          } else {
            index += 0.5;
          }
          wrap.scrollTo({ top: index });
        }
      }
      framer = requestAnimationFrame(animate);
    };
    if (radarMap.data?.RaRadarMapVOS && radarMap.data?.RaRadarMapVOS.length > 0) {
      animate();
    }
    return () => {
      cancelAnimationFrame(framer);
    };
  }, [radarMap.data?.RaRadarMapVOS, activeMap]);
  return (
    <IndexLayout>
      <div className='title-wrap'>
        <div className='topbar-left'>
          <NowDate />
        </div>
        <div className='topbar-right'>
          <div>雷达状态统计</div>
          <div>
            <span>正常：{activeLegends[0].len}</span>
            <span>弱化：{activeLegends[1].len}</span>
            <span>故障：{activeLegends[2].len}</span>
            <span>离线：{activeLegends[3].len} </span>
          </div>
        </div>
        <div className='title'>雷达健康管理云平台</div>
      </div>
      <Box title='雷达地图' className='map'>
        <div className='map-chart'>
          <div className='action'>
            <div className='zoom-action'>
              {activeMap !== 'china' && (
                <span
                  title='返回上一级'
                  className='zoom-action-item'
                  onClick={() => {
                    mapStacks.current.pop();
                    const act = mapStacks.current[mapStacks.current.length - 1];
                    setActiveMap(act);
                    setZoom(1);
                    if (act === 'china') {
                      coordinates.current = undefined;
                    } else {
                      const parentMap = mapStacks.current[mapStacks.current.length - 2];
                      const map = (
                        echarts.getMap(parentMap).geoJSON
                          .features as unknown as typeof china['features']
                      ).find((i) => `${i.properties.adcode}` === act);
                      if (map) {
                        if (map.geometry) {
                          coordinates.current = map.geometry.coordinates.flat(2) as [
                            number,
                            number
                          ][];
                        } else {
                          coordinates.current = undefined;
                        }
                      }
                    }
                  }}
                >
                  <BackwardOutlined />
                </span>
              )}
              <span
                className='zoom-action-item'
                title='放大'
                onClick={() => {
                  if (zoom < 2) {
                    setZoom(zoom + 0.1);
                  }
                }}
              >
                <PlusOutlined />
              </span>
              <span
                className='zoom-action-item'
                title='缩小'
                onClick={() => {
                  if (zoom > 0) {
                    setZoom(zoom - 0.1);
                  }
                }}
              >
                <MinusOutlined />
              </span>
            </div>
          </div>
          {data.length > 0 && (
            <div className='legend-data'>
              <div>
                {legends.map((i, index) => (
                  <div
                    key={i.name}
                    className='legend-item'
                    onClick={() => {
                      setActiveLegends((values) => ({
                        ...values,
                        [index]: { ...values[index], status: !values[index].status }
                      }));
                    }}
                  >
                    <span
                      className='icon'
                      style={{ background: activeLegends[index].status ? i.color : '#ccc' }}
                    />
                    {i.name}
                  </div>
                ))}
              </div>
              <div>
                {Object.keys(activeTypeLegends).map((key) => (
                  <div
                    key={key}
                    className='legend-item'
                    onClick={() => {
                      setActiveTypeLegends((values) => ({
                        ...values,
                        [key]: { ...values[key], status: !values[key].status }
                      }));
                    }}
                  >
                    <span
                      className='symbol'
                      style={{ color: activeTypeLegends[key].status ? 'rgb(0, 255, 156)' : '#ccc' }}
                    >
                      {getSymbol(activeTypeLegends[key].symbol)}
                    </span>
                    {key}
                  </div>
                ))}
              </div>
            </div>
          )}
          <BaseEchart
            ref={chartRef}
            style={{ height: '100%', width: '100%' }}
            lazyUpdate
            option={{
              geo: {
                map: activeMap,
                roam: true,
                zoom,
                label: {
                  show: true,
                  color: '#ccc'
                },
                itemStyle: {
                  borderColor: '#fff',
                  shadowColor: '#419bcf',
                  areaColor: '#153e7b',
                  shadowBlur: 50
                },
                emphasis: {
                  label: {
                    color: '#fff'
                  },
                  itemStyle: {
                    color: '#fff',
                    shadowColor: '#153e7b',
                    areaColor: '#419bcf'
                  }
                }
              },
              legend: {
                show: false
              },
              tooltip: {
                show: true,
                formatter: (value: any) => {
                  const [, , , , areaName = '', stationName = '', radarName = ''] =
                    value.data.value;
                  return `${areaName}${stationName} ${radarName}`;
                }
              },
              series: data.map((i) => {
                return {
                  name: i.name,
                  type: 'scatter',
                  coordinateSystem: 'geo',
                  data: i.data.filter((d: { value: number[] }) => {
                    return activeTypeLegends[d.value[3]].status && activeLegends[d.value[2]].status;
                  }),
                  symbol: icons[i.symbol as keyof typeof icons].path,
                  symbolSize: 20,
                  itemStyle: {
                    shadowBlur: 10,
                    color: (params) => {
                      return legends[(params.value as any[])[2]].color;
                    },
                    shadowOffsetY: 5
                  },
                  datasetIndex: 1
                };
              })
            }}
            onEvents={{
              georoam: (res: any) => {
                const { dx, dy } = res;
                if (dx || dy || (dx === 0 && dy === 0)) {
                  // 如果是拖拽事件就不做处理（我目前希望在缩放事件里面做相关的处理）
                  return;
                }
                // setZoom(res.zoom);
                const option = chartRef.current?.getEchartsInstance().getOption();
                if (option) {
                  setZoom((option.geo as any)[0].zoom);
                }
              },
              click: (event: any) => {
                if (event.componentType === 'geo') {
                  const map = (
                    echarts.getMap(activeMap).geoJSON
                      .features as unknown as typeof china['features']
                  ).find((i) => i.properties.name === event.name);
                  if (map) {
                    if (map.geometry) {
                      coordinates.current = map.geometry.coordinates.flat(2) as [number, number][];
                    } else {
                      coordinates.current = undefined;
                    }
                    const adcode = `${map.properties.adcode}`;
                    if (!maps.includes(adcode)) {
                      requestStatic.get(`/map/${adcode}.json`).then((data) => {
                        if (data.ok) {
                          echarts.registerMap(adcode, data.data as any);
                          setActiveMap(adcode);
                          maps.push(adcode);
                          setZoom(1);
                          mapStacks.current.push(adcode);
                        }
                      });
                    } else if (activeMap !== adcode) {
                      setActiveMap(adcode);
                      setZoom(1);
                      mapStacks.current.push(adcode);
                    }
                  }
                }
                if (event.componentType === 'series') {
                  const value = [...event.value].pop();
                  const radar = radarMap.data?.RaRadarMapVOS?.find((i) => i.id === value);
                  radar && radarClick(radar);
                }
              }
            }}
          />
        </div>
      </Box>
      <div className='right'>
        <Box className='monitor-list' title='监控信息' bodyClass='monitor-list-wrap'>
          {[
            ...activeLegends[0].values,
            ...activeLegends[1].values,
            ...activeLegends[2].values,
            ...activeLegends[3].values
          ].map((i) => (
            <div
              key={i.id}
              className={classNames(
                'monitor-list-item',
                ['perfect', 'low', 'fault', 'off'][i.status]
              )}
              title={i.name}
              onClick={() => {
                // window.location.href = `/monitor/radar?radarId=${i.id}`;
                radarClick(i);
              }}
            >
              <div className='item-content'>
                <div>{i.name}</div>
              </div>
            </div>
          ))}
        </Box>
      </div>
    </IndexLayout>
  );
};

export default Index;
